package patternmining.model.construction;

import java.util.ArrayList;

/**
 * @version 1.0, 08.07.2008
 * @author Holger Wiehen
 */

class MethodCallAnalyzer {
    
    private boolean isActivated;
    private boolean isArgumentCollecting;
    private String thisTypeName = null;
    private AttributeTypeResolver currentLocalVars;
    
    private String qualifiedTypeName;
    private MethodNameResolver methodResolver;
    private AttributeTypeResolver attributeResolver;
    private ArrayList<String> fragments;
    private String[] argumentTypes;
    
    public MethodCallAnalyzer(MethodNameResolver methodResolver, AttributeTypeResolver attributeResolver){
        this.attributeResolver = attributeResolver;
        this.methodResolver = methodResolver;
        isActivated= false;
    }
    
    public void setTypeNameOfOwnerInstance(String thisTypeName ){
        this.thisTypeName = thisTypeName;
    }
    
    
    
    public void activate(AttributeTypeResolver currentLocalVars){
        isActivated = true;
        this.currentLocalVars = currentLocalVars;
        fragments = new ArrayList<String>();
        qualifiedTypeName = null;
        isArgumentCollecting = false;
    }
    
    public void deactivate(){
        isActivated = false;
        this.currentLocalVars = null;
        fragments = null;
        argumentTypes = null;
        qualifiedTypeName = null;
        isArgumentCollecting = false;
    }
    
    public boolean isActivated(){
        return isActivated;
    }
    
    public void collectArguments(){
        isArgumentCollecting = true;
    }
    
    public boolean isArgumentCollecting(){
        return isArgumentCollecting;
    }
    
    public void addMethodCallFragment(String fragment){
        fragments.add(fragment);
    }
    
    public void setArgumentTypes(String[] argumentTypes){
        this.argumentTypes = argumentTypes;
    }
    
    public String getUniqueMethodName() throws UnknownMethodException{
        String shortMethodName = null;
        String longMethodName = null;
        String typePrefix = null;
        String uniqueMethodName = null;
        String[] arguments;
        int numFragmentos = fragments.size();
        if( numFragmentos == 1 ){
            shortMethodName = fragments.get(0);
            typePrefix = thisTypeName;
            longMethodName =  typePrefix + "." + shortMethodName;    
        }
        else if( numFragmentos == 2){
            shortMethodName = fragments.get(1);
            typePrefix = thisTypeName;
            longMethodName =  typePrefix + "." + shortMethodName;
        }
        else if( numFragmentos == 3){
            shortMethodName = fragments.get(2);
            //first check if the variable is local
            typePrefix = currentLocalVars.getAttributeType( fragments.get(1) );
            if( typePrefix == null ){
                // if the variable is not local. it is a global attribute 
                typePrefix = attributeResolver.getAttributeType( fragments.get(1) );
            }
            longMethodName =  typePrefix + "." + shortMethodName;
        }
        else{
            throw new UnknownMethodException();
        }
        // identify the unique method name, using the ParameterTypes
        uniqueMethodName = methodResolver.getUniqueMethodName( longMethodName, argumentTypes );
        return uniqueMethodName;
    }
    
    public String getObjectType() throws UnknownMethodException{
        String typePrefix = null;
        int numFragmentos = fragments.size();
        if( numFragmentos == 1 ){
            typePrefix = thisTypeName; 
        }
        else if( numFragmentos == 2){
            typePrefix = thisTypeName;
        }
        else if( numFragmentos == 3){
            //first check if the variable is local
            typePrefix = currentLocalVars.getAttributeType( fragments.get(1) );
            if( typePrefix == null ){
                // if the variable is not local. it is a global attribute 
                typePrefix = attributeResolver.getAttributeType( fragments.get(1) );
            }
        }
        else{
            throw new UnknownMethodException();
        }
        return typePrefix;
    }

    
    public void testPrint(){
        System.out.println("MethodCallAnalyser  -  Fragements recieved");
        int x = 0;
        for( String fragment : fragments ){
            x++;
            System.out.println("" + x + ". part:  " + fragment);
        }
    }
    
}